package demo.yaxin.com.myapplication;

import org.junit.Test;

import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.util.HashMap;

/**
 * 作者：张风捷特烈
 * 时间：2018/10/31 0031:8:47
 * 邮箱：1981462002@qq.com
 * 说明：初始化RecyclerView的Adapter
 */
public class Xml2ViewHolder {
    @Test
    public void main() {
        //你的布局xml所在路径
        File file = new File("E:\\project\\MyApplication\\app\\src\\main\\res\\layout\\item_test.xml");
        //你的Adapter的java类放在哪个包里
        File out = new File("E:\\project\\MyApplication\\app\\src\\main\\java\\demo\\yaxin\\com\\myapplication\\viewholder");
        //你的Adapter的名字--不要加.java
        String name = "Goods" + "ViewHolder";
        initView(file, out, name);
    }

    /**
     * 读取文件
     *
     * @param in   xml文件路径
     * @param out  输出的java路径
     * @param name
     */
    private static void initView(File in, File out, String name) {
        FileWriter fw = null;
        try {
            HashMap<String, String> map = split(readFile(in));
            String result = contactAdapter(in, out, name, map);

            //写出到磁盘
            File outFile = new File(out, name + ".java");
            fw = new FileWriter(outFile);
            fw.write(result);

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (fw != null) {
                    fw.close();
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 读取文件
     *
     * @param in
     * @return
     */
    private static String readFile(File in) {
        if (!in.exists() && in.isDirectory()) {
            return "";
        }

        FileReader fr = null;
        try {
            fr = new FileReader(in);
            //字符数组循环读取
            char[] buf = new char[1024];
            int len = 0;
            StringBuilder sb = new StringBuilder();
            while ((len = fr.read(buf)) != -1) {
                sb.append(new String(buf, 0, len));
            }

            return sb.toString();
        } catch (Exception e) {
            e.printStackTrace();
            return "";
        } finally {
            try {
                if (fr != null) {
                    fr.close();
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 直接拼接出Adapter
     */
    private static String contactAdapter(File file, File out, String name, HashMap<String, String> map) {
        StringBuilder sb = new StringBuilder();
        String path = out.getAbsolutePath();
        path.split("java");

        sb.append("package " + path.split("java\\\\")[1].replaceAll("\\\\", ".") + ";\n\n");

        sb.append("public class " + name + " extends BaseViewHolder<Integer> {\n");

        String res = readFile(file);
        HashMap<String, String> mapLayout = split(res);
        mapLayout.forEach((id, view) -> {
            sb.append("     private final ").append(view).append(" ").append(formatId2Field(id)).append(";").append("\r\n");
        });
        sb.append("\n");

        sb.append("     public " + name + " (ViewGroup parent, @LayoutRes int res) {\n\n");
        sb.append("             super(parent, res);");

        map.forEach((id, view) -> {
            sb.append("             " + formatId2Field(id))
                    .append("= $(R.id.")
                    .append(id).append(");").append("\r\n");

//            if ("Button".equals(view)) {
//                sb.append(formatId2Field(id) + ".setOnClickListener(v -> {\n" +
//                        "        });\n");
//            }
        });

        sb.append("\n       }");

        sb.append("     @Override\n" +
                "       public void setData(Integer data) {\n" +
                "               super.setData(data);\n      }\n}");

        return sb.toString();
    }

    /**
     * 连接字符串:ViewHolder
     */
    private static String contactViewHolder(HashMap<String, String> map) {
        StringBuilder sb = new StringBuilder();
        sb.append("class MyViewHolder extends RecyclerView.ViewHolder {\r\n");
        map.forEach((id, view) -> {
            if (view.contains("\n")) {
                view = view.split("\n")[0];
            }

            sb.append("public ").append(view).append(" ")
                    .append(formatId2Field(id)).append(";").append("\r\n");
        });

        sb.append("public MyViewHolder(View itemView) {\n" +
                "super(itemView);");

        map.forEach((id, view) -> {
            sb.append(formatId2Field(id))
                    .append("= itemView.findViewById(R.id.")
                    .append(id).append(");").append("\r\n");
        });
        sb.append("}\n" +
                "}\n}");

        return sb.toString();
    }

    private static String formatId2Field(String id) {
        if (id.contains("_")) {
            String[] partStrArray = id.split("_");
            id = "";
            for (String part : partStrArray) {
                String partStr = upAChar(part);
                id += partStr;
            }
        }
        return "m" + id;
    }

    /**
     * 将字符串仅首字母大写
     *
     * @param str 待处理字符串
     * @return 将字符串仅首字母大写
     */
    public static String upAChar(String str) {
        String a = str.substring(0, 1);
        String tail = str.substring(1);
        return a.toUpperCase() + tail;
    }

    private static HashMap<String, String> split(String res) {
        String[] split = res.split("<");
        HashMap<String, String> viewMap = new HashMap<>();
        for (String s : split) {
            if (s.contains("android:id=\"@+id") && !s.contains("Guideline")) {
                String id = s.split("@")[1];
                id = id.substring(id.indexOf("/") + 1, id.indexOf("\""));
                String view = s.split("\r\n")[0];
                String[] viewNameArr = view.split("\\.");
                if (viewNameArr.length > 0) {
                    view = viewNameArr[viewNameArr.length - 1];
                }
                viewMap.put(id, view);
            }
        }
        return viewMap;
    }
}
